<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { networkSurveyService } from '../services/networkSurveyService'

// 在线深度扫描任务类型（从 /tasks 获取）
type DeepTask = {
  task_id: string
  start_time?: string
  end_time?: string
  status: number   // 扫描进度（百分比）
  node_count?: number
}

// 深度扫描任务对应的节点类型（结构与攻击链页面读取的节点一致）
type DeepNode = {
  id: number
  name: string
  frontendIp: string
  backendIps: string[]
  backends: number
  rd_senstive_flage?: any
  negative_cache?: any
  frontend_query_merge_time_window?: any
  backendConfigs: Array<{
    ip: string
    query_A_times: any
    query_AAAA_times: any
    retry_total_time_window: any
    max_fanout_num: any
    backend_query_merge_time_window: any
    request_auth_times: any
    auth_time_index: any
    request_vic_times: any
    vic_time_index: any
    cluster_group?: any
  }>
  overall_auth_duration?: any
  overall_vic_duration?: any
  total_request_auth_times?: any
  total_request_vic_times?: any
}

// 在线广度扫描任务类型（沿用攻击资源测绘中的结构）
type OnlineTask = {
  task_id: string
  taskName?: string  // 任务名称
  start_ip?: string
  end_ip?: string
  status?: string
  progress: string
  scanned_ips?: number
  total_ips: number
  discovered_resolvers: number
  results?: string[]
  started_at?: string
  completed_at?: string
}

// 广度-深度总任务映射记录（/api/get_general_tasks）
type GeneralTaskMapItem = {
  general_task_id: string
  fine_task_id: string
  coarse_task_id: string
}

// ==================== 深度任务相关 ====================
const deepTasks = ref<DeepTask[]>([])
const loadingDeepTasks = ref(false)

// 每个深度任务对应的节点列表
const deepTaskNodes = ref<Record<string, DeepNode[]>>({})
const loadingDeepTaskIds = ref<Set<string>>(new Set())
const deepDetailTaskId = ref<string | null>(null)

// 节点详情弹窗
const nodeDetailModalVisible = ref(false)
const nodeDetailModalData = ref<DeepNode | null>(null)
const nodeDetailModalTaskId = ref<string | null>(null)

// ==================== 广度任务相关 ====================
const onlineTasks = ref<OnlineTask[]>([])
const loadingOnlineTasks = ref(false)
const refreshingTaskIds = ref<Set<string>>(new Set())
const onlineDetailTaskId = ref<string | null>(null)

// ==================== 广度-深度映射 ====================
const generalTasks = ref<GeneralTaskMapItem[]>([])

// ============= 通用工具函数 =============
function formatDateTime(dateTimeStr?: string): string {
  if (!dateTimeStr) return ''
  try {
    const date = new Date(dateTimeStr)
    if (isNaN(date.getTime())) return dateTimeStr

    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    const hours = String(date.getHours()).padStart(2, '0')
    const minutes = String(date.getMinutes()).padStart(2, '0')
    const seconds = String(date.getSeconds()).padStart(2, '0')

    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  } catch (e) {
    return dateTimeStr
  }
}

// 生成广度扫描任务名称：广度扫描任务-日期 时间 IP范围
function generateCoarseTaskName(
  startIp?: string,
  endIp?: string,
  startedAt?: string,
  completedAt?: string,
  taskId?: string
): string {
  const dateTime = formatDateTime(startedAt || completedAt)

  if (startIp && endIp) {
    if (dateTime) {
      return `广度扫描任务-${dateTime} ${startIp}~${endIp}`
    } else {
      return `广度扫描任务-${startIp}~${endIp}`
    }
  }

  if (dateTime) {
    return `广度扫描任务-${dateTime} ${taskId || '未知'}`
  }
  return `广度扫描任务-${taskId || '未知'}`
}

// 生成深度扫描任务名称：深度扫描任务-日期 时间
function generateDeepTaskName(startTime?: string, taskId?: string): string {
  const dateTime = formatDateTime(startTime)
  if (dateTime) {
    return `深度扫描任务-${dateTime}`
  }
  return `深度扫描任务-${taskId || '未知'}`
}

// 深度扫描任务状态显示
function formatTaskStatus(status: number): string {
  return `${status.toFixed(1)}%`
}

function getTaskStatusClass(status: number): string {
  if (status >= 100) return 'completed'
  if (status > 0) return 'running'
  return 'failed'
}

function getDeepTaskStatusLabel(status: number): string {
  if (status >= 100) return '已完成'
  if (status > 0) return '运行中'
  return '等待中'
}

function getDeepTaskStatusColor(status: number): string {
  if (status >= 100) return '#10b981'
  if (status > 0) return '#3b82f6'
  return '#f59e0b'
}

// 在线广度扫描任务状态显示
function getOnlineTaskStatusColor(status: string): string {
  switch (status) {
    case 'finished':
      return '#10b981'
    case 'running':
      return '#3b82f6'
    case 'pending':
      return '#f59e0b'
    case 'error':
      return '#ef4444'
    default:
      return '#6b7280'
  }
}

function getOnlineTaskStatusLabel(status: string): string {
  switch (status) {
    case 'finished':
      return '已完成'
    case 'running':
      return '运行中'
    case 'pending':
      return '等待中'
    case 'error':
      return '错误'
    default:
      return '未知'
  }
}

// ==================== 后端数据刷新 ====================

// 刷新在线深度扫描任务列表（从 /tasks 获取）
async function refreshDeepTasks() {
  loadingDeepTasks.value = true
  try {
    const response = await fetch('/tasks', {
      method: 'GET',
      headers: { Accept: 'application/json' }
    })
    if (!response.ok) {
      throw new Error(`获取任务列表失败: ${response.status}`)
    }
    const tasks = await response.json()
    deepTasks.value = tasks || []
    console.log('在线深度扫描任务列表:', deepTasks.value)
  } catch (error) {
    console.error('获取在线深度扫描任务列表失败:', error)
    deepTasks.value = []
    alert(
      '获取在线深度扫描任务失败: ' +
        (error instanceof Error ? error.message : '未知错误')
    )
  } finally {
    loadingDeepTasks.value = false
  }
}

// 刷新指定深度任务的节点列表（从 /api/scan-results 读取）
async function refreshDeepTaskNodes(taskId: string) {
  loadingDeepTaskIds.value.add(taskId)
  try {
    const requestData = {
      task_ids: [taskId],
      cluster_count: 1
    }

    const apiUrl = '/api/scan-results'
    console.log(`正在从任务 ${taskId} 读取节点...`, requestData)

    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json'
      },
      body: JSON.stringify(requestData)
    })

    if (!response.ok) {
      let errorMessage = `读取任务节点失败: ${response.status} ${response.statusText}`
      try {
        const errorData = await response.json()
        if (errorData.message || errorData.error || errorData.detail) {
          errorMessage += `\n详细信息: ${
            errorData.message || errorData.error || errorData.detail
          }`
        }
      } catch {
        // ignore
      }
      throw new Error(errorMessage)
    }

    const scanResults = await response.json()
    console.log('扫描结果:', scanResults)

    let allServerNodes: any[] = []

    if (Array.isArray(scanResults)) {
      allServerNodes = scanResults
    } else if (typeof scanResults === 'object' && scanResults !== null) {
      for (const key in scanResults) {
        const nodes = (scanResults as any)[key]
        if (Array.isArray(nodes)) {
          allServerNodes = allServerNodes.concat(nodes)
        }
      }
    }

    console.log(`任务 ${taskId} 共获取到 ${allServerNodes.length} 个节点`)

    let nextId = 1
    const nodes: DeepNode[] = allServerNodes.map((serverNode: any) => {
      const backendIps = Array.isArray(serverNode.backend)
        ? serverNode.backend.map((b: any) => b.ip)
        : []

      const node: DeepNode = {
        id: nextId++,
        name: `节点-${serverNode.front_IP}`,
        backends: Array.isArray(serverNode.backend)
          ? serverNode.backend.length
          : 0,
        frontendIp: serverNode.front_IP,
        backendIps,
        rd_senstive_flage: serverNode.rd_senstive_flag,
        negative_cache: serverNode.negative_cache,
        frontend_query_merge_time_window:
          serverNode.frontend_query_merge_time_window,
        backendConfigs: Array.isArray(serverNode.backend)
          ? serverNode.backend.map((b: any) => ({
              ip: b.ip,
              query_A_times: b.query_A_times,
              query_AAAA_times: b.query_AAAA_times,
              retry_total_time_window: b.retry_total_time_window,
              max_fanout_num: b.max_fanout_num,
              backend_query_merge_time_window:
                b.backend_query_merge_time_window,
              request_auth_times: b.request_auth_times,
              auth_time_index: b.auth_time_index,
              request_vic_times: b.request_vic_times,
              vic_time_index: b.vic_time_index,
              cluster_group:
                b.cluster_group !== undefined ? b.cluster_group : undefined
            }))
          : [],
        overall_auth_duration: serverNode.overall_auth_duration,
        overall_vic_duration: serverNode.overall_vic_duration,
        total_request_auth_times: serverNode.total_request_auth_times,
        total_request_vic_times: serverNode.total_request_vic_times
      }

      return node
    })

    deepTaskNodes.value[taskId] = nodes
  } catch (error) {
    console.error(`读取任务 ${taskId} 节点失败:`, error)
    alert(
      '读取任务节点失败: ' +
        (error instanceof Error ? error.message : '未知错误')
    )
    deepTaskNodes.value[taskId] = []
  } finally {
    loadingDeepTaskIds.value.delete(taskId)
  }
}

// 切换深度任务详情（如未加载节点则先刷新再展开）
async function toggleDeepDetail(taskId: string) {
  if (deepDetailTaskId.value === taskId) {
    deepDetailTaskId.value = null
    return
  }

  if (!deepTaskNodes.value[taskId] || deepTaskNodes.value[taskId].length === 0) {
    await refreshDeepTaskNodes(taskId)
  }

  deepDetailTaskId.value = taskId
}

// 打开节点详情弹窗
function openNodeDetail(taskId: string, node: DeepNode) {
  nodeDetailModalTaskId.value = taskId
  nodeDetailModalData.value = node
  nodeDetailModalVisible.value = true
}

function closeNodeDetail() {
  nodeDetailModalVisible.value = false
  nodeDetailModalData.value = null
  nodeDetailModalTaskId.value = null
}

// 刷新在线广度扫描任务（获取所有任务）
async function refreshOnlineTasks() {
  loadingOnlineTasks.value = true
  try {
    const allTasks = await networkSurveyService.getAllCoarseGrainedTasks()

    onlineTasks.value = allTasks.map((task: any) => {
      const progressNum = parseFloat(task.progress || '0')
      const status =
        progressNum >= 100 ? 'finished' : (task.status || 'running')

      return {
        task_id: task.task_id,
        taskName:
          task.taskName ||
          task.task_name ||
          generateCoarseTaskName(
            task.start_ip,
            task.end_ip,
            task.started_at,
            task.completed_at,
            task.task_id
          ),
        start_ip: task.start_ip,
        end_ip: task.end_ip,
        status,
        progress: task.progress ? `${task.progress}%` : '0%',
        scanned_ips: task.scanned_ips || task.total_ips || 0,
        total_ips: task.total_ips || 0,
        discovered_resolvers: task.discovered_resolvers || 0,
        results: task.results || [],
        started_at: task.started_at,
        completed_at: task.completed_at
      } as OnlineTask
    })

    console.log('在线广度扫描任务刷新成功:', onlineTasks.value)
  } catch (error) {
    console.error('刷新在线广度扫描任务失败:', error)
    alert(
      '刷新在线广度扫描任务失败: ' +
        (error instanceof Error ? error.message : '未知错误')
    )
  } finally {
    loadingOnlineTasks.value = false
  }
}

// 刷新单个在线广度任务
async function refreshSingleOnlineTask(taskId: string) {
  refreshingTaskIds.value.add(taskId)
  try {
    const result = await networkSurveyService.getCoarseGrainedScanResults(
      taskId
    )

    const taskIndex = onlineTasks.value.findIndex(t => t.task_id === taskId)
    const progressNum = parseFloat(
      result.progress?.replace('%', '') || '0'
    )
    const status =
      progressNum >= 100 ? 'finished' : (result.status || 'running')

    const updated: OnlineTask = {
      task_id: result.task_id || taskId,
      taskName:
        result.taskName ||
        result.task_name ||
        (taskIndex >= 0
          ? onlineTasks.value[taskIndex].taskName
          : generateCoarseTaskName(
              result.start_ip,
              result.end_ip,
              result.started_at,
              result.completed_at,
              result.task_id || taskId
            )),
      start_ip:
        result.start_ip ||
        (taskIndex >= 0 ? onlineTasks.value[taskIndex].start_ip : undefined),
      end_ip:
        result.end_ip ||
        (taskIndex >= 0 ? onlineTasks.value[taskIndex].end_ip : undefined),
      status,
      progress: result.progress || '0%',
      scanned_ips: result.scanned_ips || 0,
      total_ips: result.total_ips || 0,
      discovered_resolvers: result.discovered_resolvers || 0,
      results: result.results || [],
      started_at:
        result.started_at ||
        (taskIndex >= 0 ? onlineTasks.value[taskIndex].started_at : undefined),
      completed_at:
        result.completed_at ||
        (taskIndex >= 0
          ? onlineTasks.value[taskIndex].completed_at
          : undefined)
    }

    if (taskIndex >= 0) {
      onlineTasks.value[taskIndex] = updated
    } else {
      onlineTasks.value.push(updated)
    }

    console.log('单个在线广度任务刷新成功:', result)
  } catch (error) {
    console.error(`刷新在线广度任务 ${taskId} 失败:`, error)
    alert(
      '刷新任务失败: ' +
        (error instanceof Error ? error.message : '未知错误')
    )
  } finally {
    refreshingTaskIds.value.delete(taskId)
  }
}

// 刷新广度-深度映射表
async function refreshGeneralTasks() {
  try {
    const list = await networkSurveyService.getGeneralTasks()
    generalTasks.value = list || []
    console.log('广度-深度映射表:', generalTasks.value)
  } catch (e) {
    console.error('刷新广度-深度映射表失败:', e)
    generalTasks.value = []
  }
}

// key: 广度任务ID (onlineTasks 里的 task_id)
// value: 对应的深度任务对象 DeepTask，或 null（代表还没生成）
const coarseDeepTaskMap = computed<Record<string, DeepTask | null>>(() => {
  const map: Record<string, DeepTask | null> = {}

  // 遍历所有广度任务，为每一个广度任务找对应的深度任务
  onlineTasks.value.forEach(coarse => {
    const cid = coarse.task_id
    if (!cid) {
      return
    }

    // 在总任务表中找到与该广度任务对应的那一条记录
    const pair = generalTasks.value.find(
      item =>
        item.coarse_task_id === cid ||       // 按 coarse_task_id 匹配
        item.general_task_id === cid         // 保险：有的后端把 general_task_id 当作广度ID
    )

    // 没匹配到，或者 fine_task_id 为空 -> 没有深度任务，设为 null
    if (!pair || !pair.fine_task_id) {
      map[cid] = null
      return
    }

    // 根据 fine_task_id，在深度任务列表 /tasks 中找到真正的深度任务
    const deep = deepTasks.value.find(t => t.task_id === pair.fine_task_id)

    map[cid] = deep || null
  })

  return map
})


// 其它小交互
function toggleOnlineDetail(taskId: string) {
  if (onlineDetailTaskId.value === taskId) {
    onlineDetailTaskId.value = null
  } else {
    onlineDetailTaskId.value = taskId
  }
}

// 初始加载
onMounted(async () => {
  await refreshDeepTasks()
  await refreshOnlineTasks()
  await refreshGeneralTasks()
})
</script>

<template>
  <div class="available-resources-layout">
    <main class="available-resources-main">
      <!-- 顶部标题 -->
      <div class="page-header">
        <div class="page-title-block">
          <div class="page-title">
            任务详情
            <span class="page-badge">广度-深度联动视图</span>
          </div>
          <div class="page-subtitle">
            每一次在线广度扫描任务完成后，可在此联动查看对应深度任务链路，便于统一查看任务进度与节点结果。
          </div>
        </div>
        <div class="page-header-actions">
          <button
            class="primary-refresh-btn"
            @click="() => { refreshDeepTasks(); refreshOnlineTasks(); refreshGeneralTasks() }"
          >
            <span class="btn-icon">🔁</span>
            <span>全部刷新</span>
          </button>
        </div>
      </div>

      <!-- 顶部概要卡片 -->
      <div class="summary-row">
        <div class="summary-card">
          <div class="summary-icon summary-icon-coarse">🌐</div>
          <div class="summary-main">
            <div class="summary-title">在线广度扫描</div>
            <div class="summary-meta">
              {{ onlineTasks.length }} 个任务
              <span class="divider">·</span>
              {{ onlineTasks.filter(t => t.status === 'running').length }} 个运行中
            </div>
          </div>
        </div>
        <div class="summary-card">
          <div class="summary-icon summary-icon-deep">🧬</div>
          <div class="summary-main">
            <div class="summary-title">在线深度扫描</div>
            <div class="summary-meta">
              {{ deepTasks.length }} 个任务
              <span class="divider">·</span>
              {{ deepTasks.filter(t => t.status < 100 && t.status > 0).length }} 个运行中
            </div>
          </div>
        </div>
      </div>

      <!-- 主内容：广度-深度联动列表 -->
      <section class="main-card">
        <div class="column-header">
          <div class="column-title">
            广度-深度 联动任务列表
            <span class="column-count">{{ onlineTasks.length }} 条联动任务</span>
          </div>
        </div>

        <!-- 无任务空态 -->
        <div
          v-if="!loadingOnlineTasks && onlineTasks.length === 0"
          class="empty-state"
        >
          <div class="empty-icon">🕊</div>
          <div class="empty-title">暂无在线广度扫描任务</div>
          <div class="empty-desc">
            发起新的在线广度扫描任务后，这里将展示对应的广度-深度联动任务列表。
          </div>
        </div>

        <!-- 有任务时的联动展示 -->
        <div
          v-else
          class="linked-layout"
        >
          <div
            v-for="task in onlineTasks"
            :key="task.task_id"
            class="linked-row"
          >
            <!-- 左侧：广度扫描任务卡片 -->
            <div class="linked-left">
              <div class="task-card">
                <div class="task-header">
                  <div class="task-info">
                    <div class="task-color-dot coarse-dot"></div>
                    <div class="task-main-info">
                      <h3 class="task-name">
                        {{
                          task.taskName ||
                          generateCoarseTaskName(
                            task.start_ip,
                            task.end_ip,
                            task.started_at,
                            task.completed_at,
                            task.task_id
                          )
                        }}
                      </h3>
                      <div class="task-meta">
                        <span
                          class="status-badge"
                          :style="{ background: getOnlineTaskStatusColor(task.status || 'unknown') }"
                        >
                          {{ getOnlineTaskStatusLabel(task.status || 'unknown') }}
                        </span>
                        <span class="task-type-badge coarse-grained">广度扫描</span>
                        <span class="task-progress-text">进度: {{ task.progress }}</span>
                      </div>
                      <div
                        v-if="task.start_ip && task.end_ip"
                        class="task-time-range"
                      >
                        IP 范围: {{ task.start_ip }} - {{ task.end_ip }}
                      </div>
                    </div>
                  </div>
                  <div class="task-actions">
                    <button
                      class="action-btn refresh-single-btn"
                      @click.stop="refreshSingleOnlineTask(task.task_id)"
                      :disabled="refreshingTaskIds.has(task.task_id)"
                      title="刷新此任务"
                    >
                      <span class="btn-icon">🔄</span>
                      <span>
                        {{ refreshingTaskIds.has(task.task_id) ? '刷新中' : '刷新' }}
                      </span>
                    </button>
                    <button
                      class="action-btn detail-btn"
                      @click="toggleOnlineDetail(task.task_id)"
                    >
                      <span class="btn-icon">
                        {{ onlineDetailTaskId === task.task_id ? '🔽' : '🔍' }}
                      </span>
                      <span>
                        {{ onlineDetailTaskId === task.task_id ? '收起' : '详情' }}
                      </span>
                    </button>
                  </div>
                </div>

                <div class="progress-section">
                  <div class="progress-bar-container">
                    <div
                      class="progress-bar"
                      :style="{
                        width: task.progress && task.progress.includes('%')
                          ? task.progress
                          : (task.progress || '0') + '%'
                      }"
                    ></div>
                  </div>
                  <div class="progress-info">
                    <span>已扫描: {{ task.scanned_ips || 0 }} / {{ task.total_ips }}</span>
                    <span v-if="task.status === 'finished'">
                      发现解析器: {{ task.discovered_resolvers }}
                    </span>
                  </div>
                </div>

                <!-- 广度任务详情 -->
                <div
                  v-if="onlineDetailTaskId === task.task_id"
                  class="task-detail"
                >
                  <div class="detail-section">
                    <div class="detail-label">任务ID</div>
                    <div class="detail-content">
                      <code class="task-id">{{ task.task_id }}</code>
                    </div>
                  </div>
                  <div
                    v-if="task.start_ip && task.end_ip"
                    class="detail-section"
                  >
                    <div class="detail-label">IP范围</div>
                    <div class="detail-content">
                      <div class="ip-range">
                        <code>{{ task.start_ip }} - {{ task.end_ip }}</code>
                      </div>
                    </div>
                  </div>
                  <div class="detail-section">
                    <div class="detail-label">状态</div>
                    <div class="detail-content">
                      <span
                        class="status-badge"
                        :style="{ background: getOnlineTaskStatusColor(task.status || 'unknown') }"
                      >
                        {{ getOnlineTaskStatusLabel(task.status || 'unknown') }}
                      </span>
                    </div>
                  </div>
                  <div class="detail-section">
                    <div class="detail-label">扫描进度</div>
                    <div class="detail-content">
                      <div class="progress-info">
                        <span>{{ task.progress }}</span>
                        <span>（{{ task.scanned_ips || 0 }} / {{ task.total_ips }}）</span>
                      </div>
                    </div>
                  </div>
                  <div
                    v-if="task.started_at"
                    class="detail-section"
                  >
                    <div class="detail-label">开始时间</div>
                    <div class="detail-content">
                      <span>{{ task.started_at }}</span>
                    </div>
                  </div>
                  <div
                    v-if="task.completed_at"
                    class="detail-section"
                  >
                    <div class="detail-label">完成时间</div>
                    <div class="detail-content">
                      <span>{{ task.completed_at }}</span>
                    </div>
                  </div>
                  <div
                    class="detail-section"
                    v-if="task.status === 'finished'"
                  >
                    <div class="detail-label">DNS节点数量</div>
                    <div class="detail-content">
                      <strong>{{ task.discovered_resolvers }}</strong>
                    </div>
                  </div>
                  <div
                    class="detail-section"
                    v-if="task.status === 'finished' && task.results && task.results.length > 0"
                  >
                    <div class="detail-label">扫描结果（DNS节点IP）</div>
                    <div class="detail-content">
                      <div class="ip-list">
                        <div
                          v-for="(ip, idx) in task.results"
                          :key="idx"
                          class="ip-item"
                        >
                          <code>{{ ip }}</code>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- 中间箭头 -->
            <div class="linked-arrow">
              <div class="linked-arrow-line"></div>
              <div class="linked-arrow-label">
                <span>广度 → 深度</span>
              </div>
            </div>

            <!-- 右侧：深度扫描任务卡片 -->
            <div class="linked-right">
              <!-- 有对应深度任务 -->
              <div
                v-if="coarseDeepTaskMap[task.task_id]"
                class="task-card"
              >
                <div class="task-header">
                  <div class="task-info">
                    <div class="task-color-dot deep-dot"></div>
                    <div class="task-main-info">
                      <h3 class="task-name">
                        {{
                          generateDeepTaskName(
                            coarseDeepTaskMap[task.task_id]!.start_time,
                            coarseDeepTaskMap[task.task_id]!.task_id
                          )
                        }}
                      </h3>
                      <div class="task-meta">
                        <span
                          class="status-badge"
                          :class="getTaskStatusClass(coarseDeepTaskMap[task.task_id]!.status)"
                          :style="{
                            background: getDeepTaskStatusColor(
                              coarseDeepTaskMap[task.task_id]!.status
                            )
                          }"
                        >
                          {{ getDeepTaskStatusLabel(coarseDeepTaskMap[task.task_id]!.status) }}
                        </span>
                        <span class="task-type-badge">深度扫描</span>
                        <span class="task-progress-text">
                          进度: {{ formatTaskStatus(coarseDeepTaskMap[task.task_id]!.status) }}
                        </span>
                      </div>
                    </div>
                  </div>
                  <div class="task-actions">
                    <button
                      class="action-btn refresh-single-btn"
                      @click.stop="
                        refreshDeepTaskNodes(coarseDeepTaskMap[task.task_id]!.task_id)
                      "
                      :disabled="loadingDeepTaskIds.has(coarseDeepTaskMap[task.task_id]!.task_id)"
                      title="刷新此深度任务节点"
                    >
                      <span class="btn-icon">🔄</span>
                      <span>
                        {{
                          loadingDeepTaskIds.has(coarseDeepTaskMap[task.task_id]!.task_id)
                            ? '刷新中'
                            : '刷新'
                        }}
                      </span>
                    </button>
                    <button
                      class="action-btn detail-btn"
                      @click="toggleDeepDetail(coarseDeepTaskMap[task.task_id]!.task_id)"
                    >
                      <span class="btn-icon">
                        {{
                          deepDetailTaskId === coarseDeepTaskMap[task.task_id]!.task_id
                            ? '🔽'
                            : '🔍'
                        }}
                      </span>
                      <span>
                        {{
                          deepDetailTaskId === coarseDeepTaskMap[task.task_id]!.task_id
                            ? '收起'
                            : '查看'
                        }}
                      </span>
                    </button>
                  </div>
                </div>

                <div class="progress-section">
                  <div class="progress-bar-container">
                    <div
                      class="progress-bar"
                      :style="{ width: formatTaskStatus(coarseDeepTaskMap[task.task_id]!.status) }"
                    ></div>
                  </div>
                  <div class="progress-info">
                    <span>
                      进度: {{ formatTaskStatus(coarseDeepTaskMap[task.task_id]!.status) }}
                    </span>
                    <span>
                      节点数: {{ coarseDeepTaskMap[task.task_id]!.node_count ?? 0 }}
                    </span>
                    <span
                      v-if="coarseDeepTaskMap[task.task_id]!.start_time"
                      class="task-time"
                    >
                      {{ coarseDeepTaskMap[task.task_id]!.start_time }} ~
                      {{
                        coarseDeepTaskMap[task.task_id]!.end_time || '进行中'
                      }}
                    </span>
                  </div>
                </div>

                <!-- 深度任务节点详情（使用原来的 deepTaskNodes 渲染） -->
                <div
                  v-if="deepDetailTaskId === coarseDeepTaskMap[task.task_id]!.task_id"
                  class="task-detail"
                >
                  <div
                    v-if="
                      !deepTaskNodes[coarseDeepTaskMap[task.task_id]!.task_id] ||
                      deepTaskNodes[coarseDeepTaskMap[task.task_id]!.task_id].length === 0
                    "
                    class="detail-section"
                  >
                    <div class="detail-label">节点列表</div>
                    <div class="detail-content">
                      当前任务尚未读取到节点，请点击上方“节点刷新”按钮获取该任务的节点列表。
                    </div>
                  </div>
                  <div
                    v-else
                    class="deep-node-list"
                  >
                    <div class="deep-node-grid">
                      <div
                        v-for="node in deepTaskNodes[
                          coarseDeepTaskMap[task.task_id]!.task_id
                        ]"
                        :key="node.id"
                        class="deep-node-card"
                      >
                        <div class="deep-node-header">
                          <div class="deep-node-main">
                            <strong>{{ node.name }}</strong>
                            <span class="deep-node-meta">
                              转发器: {{ node.frontendIp }} ｜ 解析器: {{ node.backends }} 个
                            </span>
                          </div>
                        </div>
                        <div
                          v-if="node.backendIps && node.backendIps.length"
                          class="deep-node-ip-summary"
                        >
                          解析器IP:
                          <code>
                            {{
                              node.backendIps.slice(0, 3).join(', ')
                            }}{{ node.backendIps.length > 3 ? ' ...' : '' }}
                          </code>
                        </div>
                        <div class="deep-node-footer">
                          <button
                            class="action-btn detail-btn"
                            @click="openNodeDetail(coarseDeepTaskMap[task.task_id]!.task_id, node)"
                          >
                            <span class="btn-icon">🔍</span>
                            <span>节点详情</span>
                          </button>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 没有对应深度任务：灰色占位 -->
              <div
                v-else
                class="task-card placeholder-card"
              >
                <div class="task-header">
                  <div class="task-info">
                    <div class="task-color-dot deep-dot"></div>
                    <div class="task-main-info">
                      <h3 class="task-name">深度扫描任务尚未生成</h3>
                      <div class="task-meta">
                        <span
                          class="status-badge"
                          :style="{ background: '#9ca3af' }"
                        >
                          待生成
                        </span>
                        <span class="task-type-badge">深度扫描</span>
                        <span class="task-progress-text">进度: 0.0%</span>
                      </div>
                    </div>
                  </div>
                </div>
                
                <div class="progress-section">
                  <div class="progress-bar-container">
                    <div
                      class="progress-bar"
                      :style="{ width: '0%' }"
                    ></div>
                  </div>
                  <div class="progress-info">
                    <span>进度: 0.0%</span>
                    <span>节点数: 0</span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- 加载中提示（放在列表下方，防止挡住内容） -->
          <div
            v-if="loadingOnlineTasks || loadingDeepTasks"
            class="loading-state"
          >
            <div class="loading-spinner">⏳</div>
            <div class="loading-text">正在刷新任务数据...</div>
          </div>
        </div>
      </section>

      <!-- 节点详情弹窗（沿用原来的） -->
      <div
        v-if="nodeDetailModalVisible && nodeDetailModalData"
        class="node-detail-modal-mask"
        @click="closeNodeDetail"
      >
        <div
          class="node-detail-modal"
          @click.stop
        >
          <div class="node-detail-header">
            <h3>节点详情 - {{ nodeDetailModalData.name }}</h3>
            <button
              class="node-detail-close"
              @click="closeNodeDetail"
            >
              ×
            </button>
          </div>
          <div class="node-detail-body">
            <div class="detail-section">
              <div class="detail-label">所属任务</div>
              <div class="detail-content">
                <code class="task-id">{{ nodeDetailModalTaskId }}</code>
              </div>
            </div>

            <div class="detail-section">
              <div class="detail-label">转发器IP</div>
              <div class="detail-content">
                <code>{{ nodeDetailModalData.frontendIp }}</code>
              </div>
            </div>

            <div
              v-if="nodeDetailModalData.backendIps && nodeDetailModalData.backendIps.length"
              class="detail-section"
            >
              <div class="detail-label">解析器IP列表</div>
              <div class="detail-content">
                <div class="ip-list">
                  <div
                    v-for="(ip, idx) in nodeDetailModalData.backendIps"
                    :key="idx"
                    class="ip-item"
                  >
                    <code>{{ ip }}</code>
                  </div>
                </div>
              </div>
            </div>

            <div class="detail-section">
              <div class="detail-label">转发器参数</div>
              <div class="detail-content">
                <div>RD标志位敏感: {{ nodeDetailModalData.rd_senstive_flage }}</div>
                <div>负缓存: {{ nodeDetailModalData.negative_cache }}</div>
                <div>转发器合并时间窗口: {{ nodeDetailModalData.frontend_query_merge_time_window }}</div>
                <div v-if="nodeDetailModalData.overall_auth_duration !== undefined">
                  请求权威总时长: {{ nodeDetailModalData.overall_auth_duration }}
                </div>
                <div v-if="nodeDetailModalData.overall_vic_duration !== undefined">
                  请求靶标总时长: {{ nodeDetailModalData.overall_vic_duration }}
                </div>
                <div v-if="nodeDetailModalData.total_request_auth_times !== undefined">
                  请求权威总次数: {{ nodeDetailModalData.total_request_auth_times }}
                </div>
                <div v-if="nodeDetailModalData.total_request_vic_times !== undefined">
                  请求靶标总次数: {{ nodeDetailModalData.total_request_vic_times }}
                </div>
              </div>
            </div>

            <div
              v-for="(backend, bIndex) in nodeDetailModalData.backendConfigs"
              :key="bIndex"
              class="detail-section backend-section"
            >
              <div class="detail-label">解析器 {{ bIndex + 1 }}</div>
              <div class="detail-content">
                <div>IP: <code>{{ backend.ip }}</code></div>
                <div>向靶标请求A类型次数: {{ backend.query_A_times }}</div>
                <div>向靶标请求AAAA类型次数: {{ backend.query_AAAA_times }}</div>
                <div>重试时间窗口: {{ backend.retry_total_time_window }}</div>
                <div>最大并行查询域名数量: {{ backend.max_fanout_num }}</div>
                <div>解析器合并时间窗口: {{ backend.backend_query_merge_time_window }}</div>
                <div>请求权威次数: {{ backend.request_auth_times }}</div>
                <div>请求权威时间: {{ backend.auth_time_index }}</div>
                <div>请求靶标次数: {{ backend.request_vic_times }}</div>
                <div>请求靶标时间: {{ backend.vic_time_index }}</div>
                <div v-if="backend.cluster_group !== undefined">
                  聚类分组: {{ backend.cluster_group }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </main>
  </div>
</template>

<style scoped>
.available-resources-layout {
  min-height: 100%;
  background: linear-gradient(135deg, #f8fafc 0%, #e5edff 40%, #eef2ff 100%);
  display: flex;
  flex-direction: column;
  width: 100%;
}

.available-resources-main {
  flex: 1;
  padding: 16px 20px 24px;
  width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
  max-width: 100%;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* 顶部标题 */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
}

.page-title-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.page-title {
  font-size: 20px;
  font-weight: 700;
  color: #0f172a;
  display: flex;
  align-items: center;
  gap: 10px;
}

.page-subtitle {
  font-size: 13px;
  color: #6b7280;
  max-width: 640px;
}

.page-badge {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  background: #eef2ff;
  color: #4f46e5;
  border: 1px solid #c7d2fe;
}

.page-header-actions {
  display: flex;
  align-items: center;
}

.primary-refresh-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  font-size: 13px;
  border-radius: 999px;
  border: none;
  background: linear-gradient(135deg, #4f46e5, #6366f1);
  color: #ffffff;
  cursor: pointer;
  box-shadow: 0 10px 20px rgba(79, 70, 229, 0.35);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.primary-refresh-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 26px rgba(79, 70, 229, 0.45);
}

.btn-icon {
  font-size: 14px;
}

/* 顶部概要卡片（整体容器，与下方 main-card 对齐） */
.summary-row {
  display: grid;
  /* 列比例与下方联动行一致：左窄右宽，中间 90px 预留给箭头 */
  grid-template-columns: minmax(0, 0.9fr) 90px minmax(0, 1.4fr);
  column-gap: 12px;
  align-items: stretch;

  margin-bottom: 14px;
  padding: 12px 16px;
  border-radius: 18px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
}

/* 概要卡片本体（在线广度扫描 / 在线深度扫描） */
.summary-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 14px;
  background: radial-gradient(
    circle at top left,
    #e0f2fe 0%,
    #eef2ff 45%,
    #ffffff 100%
  );
  border: none;
  box-shadow: none;
}

/* 第 1 个放在第 1 列，第 2 个放在第 3 列，宽度和下方广度/深度卡片完全对齐 */
.summary-card:nth-child(1) {
  grid-column: 1;
}

.summary-card:nth-child(2) {
  grid-column: 3;
}

.summary-icon {
  width: 34px;
  height: 34px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: #fff;
  font-size: 18px;
}

.summary-icon-deep {
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
}

.summary-icon-coarse {
  background: linear-gradient(135deg, #0ea5e9, #22c55e);
}

.summary-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.summary-title {
  font-size: 14px;
  font-weight: 600;
  color: #0f172a;
}

.summary-meta {
  font-size: 12px;
  color: #6b7280;
}

.summary-meta .divider {
  margin: 0 4px;
  color: #cbd5e1;
}

/* 下方主卡片（广度-深度联动任务列表） */
.main-card {
  margin-top: 4px;
  padding: 12px 16px 16px;
  border-radius: 18px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.12);
}

/* 列表标题行 */
.column-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.column-title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  font-weight: 600;
  color: #111827;
}

.column-count {
  font-size: 12px;
  color: #6b7280;
}

/* 联动列表整体布局 */
.linked-layout {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* 每一行广度-深度联动任务之间的虚线分隔 */
.linked-row {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) 90px minmax(0, 1.4fr);
  gap: 12px;
  align-items: stretch;

  /* 为虚线留出空间 */
  position: relative;
  padding-bottom: 14px;
  margin-bottom: 14px;
}

/* 除了最后一行，其余行底部画一条虚线 */
.linked-row:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 15px;
  right: 15px;
  bottom: 0;
  border-bottom: 1px dashed #d4d4d8;
}

/* 中间箭头列 */
.linked-arrow {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.linked-arrow-line {
  width: 2px;
  height: 70px;
  border-radius: 999px;
  background: linear-gradient(180deg, #dbeafe, #a5b4fc);
  margin-bottom: 4px;
}

.linked-arrow-label {
  font-size: 12px;
  color: #6b7280;
  white-space: nowrap;
}

/* 任务列表和卡片 */
.task-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
}

.task-card {
  border-radius: 12px;
  border: 1px solid #e5e7eb;
  padding: 12px 14px;
  background: linear-gradient(135deg, #ffffff 0%, #f9fafb 100%);
  min-height: 120px;
  display: flex;
  flex-direction: column;
}

/* 广度/深度不同渐变底色 */
.linked-left .task-card {
  background: linear-gradient(135deg, #f0f9ff 0%, #ecfeff 40%, #ffffff 100%);
}

.linked-right .task-card {
  background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 40%, #ffffff 100%);
}

.task-card.placeholder-card {
  opacity: 0.6;
}

.task-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  min-height: 56px;
  margin-bottom: 8px;
}

.task-info {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.task-color-dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  flex-shrink: 0;
  margin-top: 6px;
}

.deep-dot {
  background: #6366f1;
}

.coarse-dot {
  background: #0ea5e9;
}

.task-main-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.task-name {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: #111827;
}

.task-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  font-size: 12px;
  color: #6b7280;
}

.task-time-range,
.task-time {
  margin-top: 2px;
  font-size: 12px;
  color: #6b7280;
}

.status-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  color: #ffffff;
}

.task-type-badge {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  background: #eff6ff;
  color: #1d4ed8;
}

.task-type-badge.coarse-grained {
  background: #ecfeff;
  color: #0369a1;
}

.task-progress-text {
  font-size: 12px;
  color: #4b5563;
}

.task-actions {
  display: flex;
  gap: 6px;
}

/* 统一所有动作按钮大小 */
.action-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 9px;
  font-size: 12px;
  border-radius: 999px;
  border: 1px solid #e5e7eb;
  background: #f9fafb;
  color: #374151;
  cursor: pointer;
  transition: all 0.2s ease;
  min-width: 88px;
  justify-content: center;
}

.action-btn:hover:not(:disabled) {
  background: #eff6ff;
  border-color: #bfdbfe;
  color: #1d4ed8;
}

.action-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* 进度条 */
.progress-section {
  flex-shrink: 0;
}

.progress-bar-container {
  width: 100%;
  height: 8px;
  background: #f3f4f6;
  border-radius: 999px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background: linear-gradient(90deg, #3b82f6, #22c55e);
  transition: width 0.3s ease;
}

/* 广度 vs 深度 进度条颜色 */
.linked-left .progress-bar {
  background: linear-gradient(90deg, #0ea5e9, #22c55e);
}

.linked-right .progress-bar {
  background: linear-gradient(90deg, #6366f1, #8b5cf6);
}

.progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 12px;
  color: #6b7280;
  margin-top: 4px;
}

/* 详情与节点卡片 */
.task-detail {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed #e5e7eb;
}

.detail-section {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 13px;
}

.detail-label {
  color: #6b7280;
}

.detail-content {
  color: #111827;
}

.task-id {
  font-size: 12px;
}

.ip-range {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
    'Courier New', monospace;
  font-size: 12px;
}

.ip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.ip-item {
  background: #f3f4f6;
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 12px;
}

/* 深度节点小卡片 */
.deep-node-list {
  margin-top: 8px;
}

.deep-node-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 8px;
}

.deep-node-card {
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  padding: 8px 10px;
  background: #f9fafb;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.deep-node-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.deep-node-meta {
  font-size: 12px;
  color: #6b7280;
}

.deep-node-ip-summary {
  font-size: 12px;
  color: #4b5563;
}

.deep-node-footer {
  display: flex;
  justify-content: flex-end;
}

/* 空态 & 加载态 */
.empty-state {
  padding: 32px 0 20px;
  text-align: center;
  color: #6b7280;
}

.empty-icon {
  font-size: 28px;
  margin-bottom: 6px;
}

.empty-title {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 4px;
}

.empty-desc {
  font-size: 12px;
}

.loading-state {
  margin-top: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 13px;
  color: #4b5563;
}

.loading-spinner {
  animation: rotate 1s linear infinite;
}

@keyframes rotate {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* 节点详情弹窗 */
.node-detail-modal-mask {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
}

.node-detail-modal {
  width: min(880px, 96vw);
  max-height: 80vh;
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 20px 40px rgba(15, 23, 42, 0.3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.node-detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #e5e7eb;
  background: linear-gradient(135deg, #eff6ff 0%, #eef2ff 100%);
}

.node-detail-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #111827;
}

.node-detail-close {
  border: none;
  background: transparent;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  color: #6b7280;
}

.node-detail-close:hover {
  color: #111827;
}

.node-detail-body {
  padding: 12px 16px 16px;
  overflow: auto;
}

/* 状态辅助 class */
.completed { background: #16a34a; }
.running   { background: #3b82f6; }
.failed    { background: #9ca3af; }

/* 响应式：小屏幕上下布局 */
@media (max-width: 960px) {
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .summary-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .summary-card:nth-child(1),
  .summary-card:nth-child(2) {
    grid-column: auto;
  }

  .linked-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .linked-arrow {
    display: none;
  }

  .detail-section {
    grid-template-columns: 72px 1fr;
  }
}
</style>